#!/usr/bin/env python3
import json
import subprocess
import sys
import os
import shutil
import concurrent.futures

# --- 1. 环境修复 ---
common_paths = [
    "/opt/homebrew/bin",
    "/usr/local/bin",
    "/usr/bin",
    "/bin",
    os.path.expanduser("~/.fzf/bin"),
]
current_path = os.environ.get("PATH", "")
for p in common_paths:
    if p not in current_path and os.path.exists(p):
        current_path += os.pathsep + p
os.environ["PATH"] = current_path

# 清理干扰变量
if "KITTY_SHELL_INTEGRATION" in os.environ:
    del os.environ["KITTY_SHELL_INTEGRATION"]

PREVIEW_DIR = "/tmp/kitty-tab-preview"


def get_kitty_tabs():
    try:
        result = subprocess.run(
            ["kitty", "@", "ls"], capture_output=True, text=True, check=True
        )
        data = json.loads(result.stdout)
    except Exception:
        sys.exit(1)

    parsed_tabs = []
    for os_window in data:
        for tab in os_window.get("tabs", []):
            if not tab.get("windows"):
                continue
            win = tab["windows"][0]

            # 获取进程名
            fg_procs = win.get("foreground_processes", [])
            cmdline = fg_procs[0].get("cmdline", []) if fg_procs else []
            proc_name = cmdline[0].split("/")[-1] if cmdline else "shell"

            # 组合标题
            parts = [proc_name, tab.get("title", ""), win.get("cwd", "")]
            display_title = " | ".join([str(p) for p in parts if p])

            parsed_tabs.append(
                {
                    "id": tab["id"],
                    "is_focused": tab.get("is_focused", False),
                    "display": display_title,
                    "win_id": win["id"],
                }
            )

    # 排序：当前聚焦的排第一
    parsed_tabs.sort(key=lambda x: (not x["is_focused"], x["display"]))
    return parsed_tabs


def generate_preview(tab):
    """
    生成预览文件。
    关键修复：如果 Tab 是当前聚焦的(is_focused=True)，跳过抓取！
    防止干扰正在运行的动态程序(如 top)。
    """
    path = os.path.join(PREVIEW_DIR, str(tab["id"]))

    # --- 关键修改开始 ---
    if tab["is_focused"]:
        # 对于当前窗口，直接写入一个提示文本，不调用 get-text
        try:
            with open(path, "w") as f:
                f.write("(Current Tab - Preview Skipped)")
        except:
            pass
        return
    # --- 关键修改结束 ---

    try:
        with open(path, "w") as f:
            # 使用 get-text 抓取其他后台窗口是安全的
            subprocess.run(
                [
                    "kitty",
                    "@",
                    "get-text",
                    "--match",
                    f"id:{tab['win_id']}",
                    "--ansi",
                    "--extent=screen",
                ],
                stdout=f,
                stderr=subprocess.DEVNULL,
            )
    except:
        pass


def main():
    if os.path.exists(PREVIEW_DIR):
        shutil.rmtree(PREVIEW_DIR)
    os.makedirs(PREVIEW_DIR, exist_ok=True)

    tabs = get_kitty_tabs()
    if not tabs:
        sys.exit(0)

    # 并发生成预览
    with concurrent.futures.ThreadPoolExecutor(max_workers=12) as executor:
        executor.map(generate_preview, tabs)

    fzf_input = "\n".join([f"{t['id']} | {t['display']}" for t in tabs])

    # FZF 命令
    fzf_cmd = [
        "fzf",
        "--ansi",
        "--height=100%",
        "--layout=reverse",
        "--cycle",
        "--border=none",
        "--list-border=rounded",
        "--info=hidden",
        "--preview-window=down,50%,border-none",
        # 预览逻辑：读取对应的文件
        f"--preview=cat {PREVIEW_DIR}/$(echo {{}} | awk '{{print $1}}')",
    ]

    try:
        proc = subprocess.Popen(
            fzf_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True
        )
        stdout, _ = proc.communicate(input=fzf_input)

        if proc.returncode == 0 and stdout.strip():
            selected_id = stdout.split(" | ")[0].strip()
            subprocess.run(["kitty", "@", "focus-tab", "--match", f"id:{selected_id}"])

    except FileNotFoundError:
        print("Error: fzf not found.")

    if os.path.exists(PREVIEW_DIR):
        shutil.rmtree(PREVIEW_DIR)


if __name__ == "__main__":
    main()
